package com.sc.common.service.impl;


import cn.cs.mathgo.common.entity.BaseVo;
import cn.cs.mathgo.common.service.BaseService;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.StringUtils;
import cn.cs.mathgo.common.entity.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sc.common.service.BaseService;

import java.lang.reflect.Field;
import java.util.*;

public class BaseServiceImpl<U  extends BaseMapper<T>,T>extends ServiceImpl<U, T> implements BaseService<T> {
    /**
     * 根据传入的vo对象查询实体
     * @param entity
     * @param <M>
     * @return
     */
    public <M> List<T> queryByVo(M entity){
        Class<M> aClass =  (Class<M>)entity.getClass();
        Map<String, Object> fieldValueMap = getFieldValueMapByVo(entity);
        List<T> ts = this.selectByMap(fieldValueMap);
        return ts;
    }

    /**
     * 根据vo分页查询
     * @param entity
     * @param <M>
     * @return
     */
    public <M extends BaseVo> Page<T> queryPage(M entity){
        Class<M> aClass =  (Class<M>)entity.getClass();
        Map<String, Object> fieldValueMap = getFieldValueMapByVo(entity);
        Integer p =entity.getCurrentPage();
        Integer size=entity.getSize();
        List<String> like = entity.getLike();
        Wrapper<T> wrapper=new EntityWrapper<T>();
        Iterator it = fieldValueMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String key = (String)entry.getKey();
            Object value = entry.getValue();
            if(key.equals("like")){
                continue;
            }
            else  if(wrapper.isEmptyOfWhere()){
                if(like.contains(key)){
                    wrapper.where("").like(key,value+"");
                }else
                    wrapper.where(key+"={0}",value);
            }else {
                if(like.contains(key)){
                    wrapper.like(key,value+"");
                }else wrapper.and(key+"={0}",value);
            }
        }
        wrapper.orderDesc(Arrays.asList("createdDt"));
        PageHelper.startPage(p,size);
        List<T>list = this.selectList( wrapper);
        PageInfo<T> pageInfo = new PageInfo<>(list);
        Page<T> page =new Page<T>(pageInfo);
        return  page;
    }

    /**
     * 根据实体查询
     * @param  t
     * @return
     */
    public  List<T> queryByEntity(T t){
        Map<String, Object> fieldValueMap = this.getFieldValueMap(t);
        List<T> ts = this.selectByMap(fieldValueMap);
        return ts;
    }











    private <M> Map<String,Object> getFieldValueMapByVo(M t) {
        // key是属性名，value是对应值
        Map<String, Object> fieldValueMap = new HashMap<String, Object>();
        Class<M> aClass =  (Class<M>) t.getClass();
        // 获取当前加载的实体类中所有属性（字段）
        Field[] fields = aClass.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field f = fields[i];
            String key = f.getName();// 属性名
            Object value = null;//属性值
            if (! "serialVersionUID".equals(key)) {// 忽略序列化版本ID号

                f.setAccessible(true);// 取消Java语言访问检查
                try {
                    value =f.get(t);
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                if(value!=null){
                    if(value instanceof  String ){
                            if(org.apache.commons.lang3.StringUtils.isBlank((String)value)){
                                    continue;
                            }
                    }
                    key=StringUtils.camelToUnderline(key);
                    fieldValueMap.put(key, value);
                }

            }
        }
        return fieldValueMap;
    }
    /**
     * 获取指定实例的所有属性名及对应值的Map实例
     * @param t
     * @return 字段名及对应值的Map实例
     */
    private Map<String, Object> getFieldValueMap(T t) {
        // key是属性名，value是对应值
        Map<String, Object> fieldValueMap = new HashMap<String, Object>();
        Class<T> aClass =  (Class<T>) t.getClass();
        // 获取当前加载的实体类中所有属性（字段）
        Field[] fields = aClass.getDeclaredFields();

        for (int i = 0; i < fields.length; i++) {
            Field f = fields[i];
            String key = f.getName();// 属性名
            Object value = null;//属性值
            if (! "serialVersionUID".equals(key)) {// 忽略序列化版本ID号

                f.setAccessible(true);// 取消Java语言访问检查
                try {
                    value =f.get(t);
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                if(value!=null){
                    key=StringUtils.camelToUnderline(key);
                    fieldValueMap.put(key, value);
                }

            }
        }
        return fieldValueMap;
    }
}
